package mockexample;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.*;

public class MockAnnotationExample {

    @Mock
    private List mockList;
    
    public MockAnnotationExample() {
        super();
        MockitoAnnotations.openMocks(this);
    }

    @Test
    public void shorthand(){
        mockList.add(1);
        verify(mockList).add(1);
    }
    
    @Test
    public void with_unspecified_arguments(){
        List list = mock(List.class);
        //匹配任意参数
        when(list.get(anyInt())).thenReturn(1);
        
        assertEquals(1, list.get(1));
        assertEquals(1, list.get(999));
//        assertTrue(list.contains(1));
        assertTrue(!list.contains(3));
    }
    
    @Test
    @DisplayName("部分使用真实对象")
    public void real_partial_mock(){
        //通过spy来调用真实的api
        List list = spy(new ArrayList());
        assertEquals(0,list.size());
        A a  = mock(A.class);
        //通过thenCallRealMethod来调用真实的api
        when(a.doSomething(anyInt())).thenCallRealMethod();
        assertEquals(999,a.doSomething(999));
    }


    class A{
        public int doSomething(int i){
            return i;
        }
    }
    
    @Test
    public void spy_on_real_objects(){
        List list = new LinkedList();
        
        List spy = spy(list);
        //下面预设的spy.get(0)会报错，因为会调用真实对象的get(0)，所以会抛出越界异常
//        when(spy.get(0)).thenReturn(3);

        //使用doReturn-when可以避免when-thenReturn调用真实对象api
        doReturn(999).when(spy).get(999);
        
        //预设size()期望值
        when(spy.size()).thenReturn(100);
       
        //调用真实对象的api
        spy.add(1);
        spy.add(2);
        assertEquals(100,spy.size());
//        assertEquals(1,spy.get(0));
//        assertEquals(2,spy.get(1));
//        verify(spy).add(1);
//        verify(spy).add(2);
//        assertEquals(999,spy.get(999));
//        spy.get(2);
    }
}
